package co.fitstart.admin.dao;

import java.util.List;

import com.demo2do.core.persistence.annotation.Dynamic;
import com.demo2do.core.persistence.annotation.Execute;
import com.demo2do.core.persistence.annotation.Limit;
import com.demo2do.core.persistence.annotation.Query;
import com.demo2do.core.persistence.annotation.Variable;

import co.fitstart.entity.course.round.CourseRound;
import co.fitstart.entity.course.schedule.CourseSchedule;
import co.fitstart.entity.course.schedule.ScheduleStatus;
import co.fitstart.entity.courseware.dietary.Dietary;
import co.fitstart.entity.courseware.dietary.DietaryProgram;
import co.fitstart.entity.courseware.dietary.DietaryProgramType;
import co.fitstart.entity.courseware.exercise.Exercise;
import co.fitstart.entity.courseware.exercise.PlannedSchedule;
import co.fitstart.entity.courseware.fitnessgroup.BatchCourseware;
import co.fitstart.entity.courseware.fitnessgroup.BatchCoursewareType;
import co.fitstart.entity.courseware.fitnessgroup.Courseware;
import co.fitstart.entity.courseware.fitnessgroup.CoursewareEditStatus;
import co.fitstart.entity.courseware.fitnessgroup.CoursewareMovementType;
import co.fitstart.entity.courseware.fitnessgroup.DailyCourseware;

@Dynamic("hibernate")
public interface GroupDao {
    
    /**
     * 
     * @param courseRound
     * @param type
     * @return
     */
    @Query("FROM BatchCourseware WHERE disabled = false AND courseRound = :courseRound AND type = :type ORDER BY sorting ASC")
    public List<BatchCourseware> listBatchCourseware(@Variable("courseRound") CourseRound courseRound, @Variable("type") BatchCoursewareType type);
    
    /**
     * 
     * @param courseRound
     * @return
     */
    @Query("FROM BatchCourseware WHERE disabled = false AND courseRound = :courseRound AND editStatus != 2")
    public List<BatchCourseware> listBatchCourseware(@Variable("courseRound") CourseRound courseRound);
    
    /**
     * 
     * @param roundId
     * @param sorting
     * @return
     */
    @Query("FROM BatchCourseware WHERE disabled = false AND courseRound.id = :roundId AND sorting = :sorting")
    public BatchCourseware loadBatchCourseware(@Variable("roundId") Long roundId, @Variable("sorting") int sorting);
    
    /**
     * 
     * @param roundId
     * @param sorting
     * @param type
     * @return
     */
    @Query("FROM BatchCourseware WHERE disabled = false AND courseRound.id = :roundId AND sorting = :sorting AND type = :type")
    public BatchCourseware loadBatchCourseware(@Variable("roundId") Long roundId, @Variable("sorting") int sorting, @Variable("type") BatchCoursewareType type);
    
    /**
     * 
     * @param batchCourseware
     * @return
     */
    @Query("FROM DailyCourseware WHERE disabled = false AND batch = :batch")
    public List<DailyCourseware> listDailyCourseware(@Variable("batch") BatchCourseware batchCourseware);
    
    /**
     * 
     * @param batchCourseware
     * @param sorting
     * @return
     */
    @Query("FROM DailyCourseware WHERE disabled = false AND batch = :batch AND sorting = :sorting")
    public DailyCourseware loadDailyCourseware(@Variable("batch") BatchCourseware batchCourseware, @Variable("sorting") int sorting);
    
    /**
     * 
     * @param batch
     */
    @Execute("UPDATE DailyCourseware SET roundwareStatus = 2, editStatus = 2 WHERE disabled = false AND batch = :batch AND editStatus = 1")
    public void updateDailyStatus(@Variable("batch") BatchCourseware batch);
    
    /**
     * 
     * @param batch
     * @param webLink
     */
    @Execute("UPDATE DailyCourseware SET roundwareStatus = 2, editStatus = 2, webLink = :webLink WHERE disabled = false AND batch = :batch AND editStatus = 1")
    public void updateDailyStatus(@Variable("batch") BatchCourseware batch, @Variable("webLink") String webLink);
    
    /**
     * 
     * @param batch
     */
    @Execute("UPDATE DailyCourseware SET editStatus = 1 WHERE disabled = false AND batch = :batch")
    public void saveAllDaily(@Variable("batch") BatchCourseware batch);
    
    /**
     * 
     * @param roundId
     * @return
     */
    @Query("FROM BatchCourseware WHERE disabled = false AND courseRound.id = :roundId")
    public BatchCourseware loadBatchCourseware(@Variable("roundId") Long roundId);
    
    /**
     * 
     * @param courseRound
     * @return
     */
    @Query("FROM BatchCourseware WHERE disabled = false AND courseRound = :courseRound")
    public List<BatchCourseware> loadBatchCourseware(@Variable("courseRound") CourseRound courseRound);
    
    /**
     * 
     * @param courseRound
     * @param sorting
     * @return
     */
    @Query("FROM BatchCourseware WHERE disabled = false AND courseRound = :courseRound AND sorting = :sorting")
    public BatchCourseware loadBatchCourseware(@Variable("courseRound") CourseRound courseRound, @Variable("sorting") int sorting);
    
    /**
     * 
     * @param courseRound
     * @param type
     * @param sorting
     * @return
     */
    @Query("FROM BatchCourseware WHERE disabled = false AND courseRound = :courseRound AND type = :type AND sorting = :sorting")
    public BatchCourseware loadBatchCourseware(@Variable("courseRound") CourseRound courseRound, @Variable("type") BatchCoursewareType type, @Variable("sorting") int sorting);
    
    /**
     * 
     * @param batchCourseware
     * @return
     */
    @Query("FROM DailyCourseware WHERE disabled = false AND editStatus != 2 AND batch = :batch")
    public List<DailyCourseware> listUnfinishDailyCourseware(@Variable("batch") BatchCourseware batchCourseware);
    
    /**
     * 
     * @param dailyCourseware
     * @return
     */
    @Query("FROM Courseware WHERE disabled = false AND daily = :daily ORDER BY ranking ASC,id ASC")
    public List<Courseware> listCourseware(@Variable("daily") DailyCourseware dailyCourseware);
    
    /**
     * 
     * @param dailyCourseware
     */
    @Execute("UPDATE Courseware SET disabled = true WHERE disabled = false AND daily = :daily") 
    public void deleteCourseware(@Variable("daily") DailyCourseware dailyCourseware);
    
    /**
     * 
     * @param batchCourseware
     * @param type
     * @return
     */
    @Query("FROM DietaryProgram WHERE disabled = false AND batch = :batch AND type = :type")
    public DietaryProgram loadDietaryProgram(@Variable("batch") BatchCourseware batchCourseware, @Variable("type") DietaryProgramType type);
    
    /**
     * 
     * @param courseRound
     * @return
     */
    @Query("FROM Dietary WHERE disabled=false AND batch.disabled=false AND batch.courseRound=:courseRound")
    public List<Dietary> listDietary(@Variable("courseRound") CourseRound courseRound);
    
    /**
     * 
     * @param courseRound
     * @param editStatus
     * @return
     */
    @Query("FROM Dietary WHERE disabled=false AND batch.disabled=false AND batch.editStatus=:editStatus AND batch.courseRound=:courseRound")
    public List<Dietary> listDietary(@Variable("courseRound") CourseRound courseRound, @Variable("editStatus") CoursewareEditStatus editStatus);
    
    /**
     * 
     * @param courseRound
     * @return
     */
    @Query("FROM Exercise WHERE disabled=false AND batch.disabled=false AND batch.courseRound=:courseRound")
    public List<Exercise> listExercise(@Variable("courseRound") CourseRound courseRound);
    
    /**
     * 
     * @param courseRound
     * @param editStatus
     * @return
     */
    @Query("FROM Exercise WHERE disabled=false AND batch.disabled=false AND batch.editStatus=:editStatus AND batch.courseRound=:courseRound")
    public List<Exercise> listExercise(@Variable("courseRound") CourseRound courseRound, @Variable("editStatus") CoursewareEditStatus editStatus);
    
    /**
     * 
     * @param courseRound
     * @return
     */
    @Query("FROM PlannedSchedule WHERE disabled=false AND batch.disabled=false AND batch.courseRound=:courseRound AND content IS NOT NULL ORDER BY batch.sorting ASC,day ASC")
    public List<PlannedSchedule> listPlannedSchedule(@Variable("courseRound") CourseRound courseRound);
    
    /**
     * 
     * @param courseRound
     * @param editStatus
     * @return
     */
    @Query("FROM PlannedSchedule WHERE disabled=false AND batch.disabled=false AND batch.editStatus=:editStatus AND batch.courseRound=:courseRound AND content IS NOT NULL ORDER BY batch.sorting ASC,day ASC")
    public List<PlannedSchedule> listPlannedSchedule(@Variable("courseRound") CourseRound courseRound, @Variable("editStatus") CoursewareEditStatus editStatus);
    
    /**
     * 
     * @param courseRound
     * @param scheduleStatus
     * @param beginIndex
     * @param maxResult
     * @return
     */
    @Limit
    @Query("FROM CourseSchedule WHERE disabled=false AND courseRound=:courseRound AND scheduleStatus IN (:scheduleStatus) ORDER BY occurDate ASC,occurHour ASC")
    public List<CourseSchedule> listCourseSchedule(@Variable("courseRound") CourseRound courseRound, @Variable("scheduleStatus") ScheduleStatus[] scheduleStatus, @Variable("beginIndex") int beginIndex, @Variable("maxResult") int maxResult);
    
    /**
     * 
     * @param courseRound
     * @param course
     * @return
     */
    @Query("FROM Courseware WHERE disabled=false AND daily.disabled=false AND daily.batch.disabled=false AND daily.batch.type=:course AND daily.batch.courseRound=:courseRound ORDER BY daily.sorting ASC,id ASC")
    public List<Courseware> listCourseware(@Variable("courseRound") CourseRound courseRound, @Variable("course") BatchCoursewareType course);
    
    /**
     * 
     * @param courseSchedule
     * @return
     */
    @Query("FROM Courseware WHERE disabled=false AND courseSchedule=:courseSchedule")
    public List<Courseware> listCourseware(@Variable("courseSchedule") CourseSchedule courseSchedule);
    
    /**
     * 
     * @param dailyCourseware
     * @param type
     * @return
     */
    @Query("FROM Courseware WHERE disabled=false AND daily=:daily AND type=:type ORDER BY id ASC")
    public List<Courseware> listCourseware(@Variable("daily") DailyCourseware dailyCourseware, @Variable("type") CoursewareMovementType type);
    
    /**
     * 
     * @param dailyCourseware
     * @param type
     * @param ranking
     * @return
     */
    @Query("FROM Courseware WHERE disabled=false AND daily=:daily AND type=:type AND ranking=:ranking")
    public Courseware getCourseware(@Variable("daily") DailyCourseware dailyCourseware, @Variable("type") CoursewareMovementType type, @Variable("ranking") int ranking);
    
    /**
     * 
     * @param dailyCourseware
     * @param type
     * @param ranking
     */
    @Execute("UPDATE Courseware SET ranking=ranking-1 WHERE disabled=false AND daily=:daily AND type=:type AND ranking>:ranking")
    public void riseRankingBehind(@Variable("daily") DailyCourseware dailyCourseware, @Variable("type") CoursewareMovementType type, @Variable("ranking") int ranking);

    /**
     * 
     * @param batch
     * @return
     */
    @Query("FROM Dietary WHERE disabled = false AND batch = :batch")
    public Dietary loadDietary(@Variable("batch") BatchCourseware batch);

    /**
     * 
     * @param courseRound
     * @param sorting
     */
    @Execute("UPDATE BatchCourseware SET disabled = true WHERE courseRound = :courseRound AND sorting > :sorting")
    public void disableBatchCourseware(@Variable("courseRound") CourseRound courseRound, @Variable("sorting") int sorting);

    /**
     * 
     * @param courseRound
     * @param sorting
     * @return
     */
    @Query("FROM Dietary dietary WHERE dietary.disabled = false AND dietary.batch.courseRound = :courseRound AND dietary.batch.sorting > :sorting")
    public List<Dietary> listDieatry(@Variable("courseRound") CourseRound courseRound, @Variable("sorting") int sorting);

    /**
     * 
     * @param courseRound
     * @param sorting
     * @return
     */
    @Query("FROM Exercise exercise WHERE exercise.disabled = false AND exercise.batch.courseRound = :courseRound AND exercise.batch.sorting > :sorting")
    public List<Exercise> listExercise(@Variable("courseRound") CourseRound courseRound, @Variable("sorting") int sorting);

    /**
     * 
     * @param courseRound
     * @param type
     * @param maxSorting
     * @param editStatus
     * @return
     */
    @Query("SELECT COUNT(DISTINCT sorting) FROM BatchCourseware WHERE disabled = false AND courseRound = :courseRound AND type = :type AND sorting <= :maxSorting AND editStatus = :editStatus")
    public int countBatchCourseware(@Variable("courseRound") CourseRound courseRound, @Variable("type") BatchCoursewareType type, @Variable("maxSorting") int maxSorting, @Variable("editStatus") CoursewareEditStatus editStatus);

    /**
     * 有上课课件且上课时间最大的课时
     * @param courseRound
     * @return
     */
    @Query("SELECT courseware.courseSchedule FROM Courseware courseware WHERE courseware.disabled = false AND courseware.groupAmount != 0 AND courseware.movementNumber != 0 AND courseware.courseSchedule.disabled = false AND courseware.courseSchedule.occurDate IS NOT NULL AND courseware.courseSchedule.occurHour IS NOT NULL AND courseware.courseSchedule.courseRound = :courseRound ORDER BY courseware.courseSchedule.occurDate DESC, courseware.courseSchedule.occurHour DESC")
    public CourseSchedule loadCourseSchedue(@Variable("courseRound") CourseRound courseRound);
}
